/**
 * 用户相关服务
 * @authors 杨兴洲（of2502）
 * @date    2017/3/3 11:43
 * @version 1.0
 */

import User from '../model/user';
import WxAuthorizerService from './weixin-authorizer-service';
import TokenService from './token-service';

export default class UserService {
  static async getList(page, pageSize): Promise<any> {
    return await User.find({}, { userID: 1, _id: 0 })
      .sort({ createdAt: -1 })
      .skip(pageSize * (page - 1))
      .limit(+pageSize);
  }

  static userExist(userID: string): Promise<any> {
    return new Promise((resolve, reject) => {
      User.count({ userID }).exec((err, data) => {
        resolve(err ? false : !!data);
      });
    });
  }

  static async getInfo(userID: string): Promise<any> {
    return (await User.findOne({ userID }, { _id: 0, ___v: 0 })) || {};
  }

  static async getInfoByAppID(AppID: string): Promise<any> {
    return (await User.findOne({ authorizer_appid: AppID }, { _id: 0, ___v: 0 })) || {};
  }

  static async getUsedAdNewsList(userID: string): Promise<any> {
    let info: any = await User.findOne({ userID }, { adNewsUsedList: 1 });
    return info.adNewsUsedList || [];
  }

  static async updateAdNewsList({ userID, list }: { userID; list: string[] }): Promise<any> {
    return await User.findOneAndUpdate({ userID }, { adNewsUsedList: list }, { new: true });
  }

  static async setInfo(userID: string, data: object): Promise<any> {
    return await User.findOneAndUpdate({ userID }, data, { upsert: true });
  }

  static async updateInfo(userID: string, data: object): Promise<any> {
    return await User.findOneAndUpdate({ userID }, data, { upsert: true });
  }

  static async removeInfo(userID: string): Promise<any> {
    return await User.findOneAndRemove({ userID });
  }

  static async removeInfoByAppID(AppID: string): Promise<any> {
    return await User.findOneAndRemove({ authorizer_appid: AppID });
  }

  /**
     * 获取access_token
     * 验证是否过期
     * @param userID
     * @returns {Promise<string>}
     */
  static async getAccessToken(userID: string): Promise<string> {
    // 判断access_token是否过期
    let result = await TokenService.getToken(userID);
    if (!result || !result.token) {
      let { authorizer_refresh_token, authorizer_appid } = await UserService.getInfo(userID);
      let { authorizer_access_token } = await WxAuthorizerService.refreshAuthToken({
        authorizer_refresh_token,
        authorizer_appid
      });
      // 更新数据库
      await TokenService.create({ userID, token: authorizer_access_token });
      return authorizer_access_token;
    }

    return result.token;
  }

  /**
     * 获取access_token 及过期时间
     * @param userID
     * @returns {Promise<any>}
     */
  static async getAccessTokenInfo(userID: string): Promise<any> {
    // 判断access_token是否过期
    let { token: accessToken, expireAt: expiresTime } = await TokenService.getToken(userID);
    if (!accessToken) {
      let { authorizer_refresh_token, authorizer_appid } = await UserService.getInfo(userID);
      let { authorizer_access_token, expires_in } = await WxAuthorizerService.refreshAuthToken({
        authorizer_refresh_token,
        authorizer_appid
      });
      // 更新数据库
      await TokenService.create({ userID, token: authorizer_access_token });
      return {
        accessToken: authorizer_access_token,
        expiresTime: new Date(+new Date() + (expires_in - 200) * 1000).getTime()
      };
    }
    return { authToken: accessToken, authExpiresTime: expiresTime.getTime() };
  }

  /**
     * 获取jsapiTicket信息
     * @param userID
     * @returns {Promise<{jsapiTicket, jsapiTicketExpireAt}>}
     */
  static async getJSApiTicket(userID) {
    let { jsapiTicket, jsapiTicketExpireAt } = await UserService.getInfo(userID);
    if (!jsapiTicket) {
      let { ticket, expires_in } = await WxAuthorizerService.getJSApiTicket(await UserService.getAccessToken(userID));
      jsapiTicket = ticket;
      jsapiTicketExpireAt = new Date(+new Date() + (expires_in - 200) * 1000);
      // 更新数据库
      await UserService.updateInfo(userID, { ticket: jsapiTicket, ticketExpireAt: jsapiTicketExpireAt });
    }
    return { jsapiTicket, jsapiTicketExpireAt };
  }

  /**
     * 获取所有的公众号相关的信息
     * @param userID
     * @returns {Promise<{appId, accessToken, expiresTime, jsapiTicket, jsapiTicketExpiresTime: number}>}
     */
  static async getAvailableInfo(userID: string): Promise<any> {
    //获取token及过期时间
    let { token, expireAt } = await TokenService.getToken(userID);
    let {
      authorizer_refresh_token,
      authorizer_appid: appId,
      jsapiTicket,
      jsapiTicketExpireAt: jsapiTicketExpiresTime
    } = await UserService.getInfo(userID);
    if (!token) {
      let { authorizer_access_token, expires_in } = await WxAuthorizerService.refreshAuthToken({
        authorizer_refresh_token,
        authorizer_appid: appId
      });
      // 更新数据库
      token = authorizer_access_token;
      await TokenService.create({ userID, token });
      expireAt = new Date(+new Date() + (expires_in - 200) * 1000);
    }
    if (!jsapiTicket) {
      let { ticket, expires_in } = await WxAuthorizerService.getJSApiTicket(await UserService.getAccessToken(userID));
      jsapiTicket = ticket;
      jsapiTicketExpiresTime = new Date(+new Date() + (expires_in - 200) * 1000);
      // 更新数据库
      await UserService.updateInfo(userID, { ticket: jsapiTicket, ticketExpireAt: jsapiTicketExpiresTime });
    }
    return {
      appId,
      authToken: token,
      authExpiresTime: expireAt.getTime(),
      jsapiTicket,
      jsapiTicketExpiresTime: jsapiTicketExpiresTime.getTime()
    };
  }
}
